#ifdef MEM_DEBUG
#include <stdlib.h>
#include <iostream>
#include <ostream>
#include <fstream>
#include "ReportError.h"
#include <windows.h>
#include "Memory.h"

#undef new
static int depth = 0;
static int AmountofBytesUsed = 0;
void* operator new(size_t size, int LineNumber, std::string FileName)
{
	void* Mem =  malloc(size);

	depth++;
	if(depth == 1)
	{
		TheAllocationManager::Instance()->CreateAllocation(Allocation(Mem, size, LineNumber, FileName));
		//TheAllocationManager::Instance()->MemoryUseage(true, size);
		//TheAllocationManager::Instance()->Print();
	}

	depth--;
	return Mem;
}

void operator delete(void* p)
{
	depth++;
	if(depth == 1)
	{
		//TheAllocationManager::Instance()->MemoryUseage(false, TheAllocationManager::Instance()->ReturnSize(p));
		//TheAllocationManager::Instance()->Print();
		TheAllocationManager::Instance()->RemoveAllocation(p);
	}
	depth--;
	if(p)
	{
		free(p);
	}

}

void AllocationManager::Print() 
{
	//Some code from http://www.cplusplus.com/doc/tutorial/files/

	std::ofstream myfile;
	myfile.open ("Leaks.txt");

	if(TheAllocMap.size() != 0)
	{
		ReportError("OH GOD LEAKS! Check Leaks.txt \n");
	}
	else
	{
		myfile << "No Leaks here... \n";
	}


	
	for(std::map<void*, Allocation>::iterator it = TheAllocMap.begin(); it != TheAllocMap.end(); ++it)
	{
		myfile << it->second;
	}
	myfile.close();
}

Allocation::Allocation()
{
	m_Addr = nullptr;
	m_Size = 0;
}

Allocation::Allocation(void* Addr, size_t Size, int Number, std::string Name)
{
	m_Addr = Addr;
	m_Size = Size;
	m_LineNumber = Number;
	m_FileName = Name;
}

void AllocationManager::CreateAllocation(Allocation a)
{
	TheAllocMap[a.m_Addr] = a;
}

void AllocationManager::RemoveAllocation(void* a)
{
	TheAllocMap.erase(a);
}

size_t AllocationManager::ReturnSize(void* a)
{
	size_t Result = TheAllocMap[a].m_Size;
	return Result;
}

int AllocationManager::MemoryUseage(bool New, size_t size)
{
	if(New)
	{
		AmountofBytesUsed += size;
	}
	else
	{
		AmountofBytesUsed -= size;
	}

	//std::cout << "Amount of Bytes used: " << AmountofBytesUsed << "\n";
	return AmountofBytesUsed;
}

AllocationManager::~AllocationManager()
{
	depth++;
	TheAllocationManager::Instance()->Print();
}

#endif